﻿
//////////////////////////////////////////////////////////////////////////
// ANInput class
//////////////////////////////////////////////////////////////////////////

function ANInput() {
	var thisANInput = this;

	this.onKeyDown = function (keyCode, character, isCtrlPressed, isShiftPressed, isAltPressed) { };
	this.onKeyUp = function (keyCode, character, isCtrlPressed, isShiftPressed, isAltPressed) { };
	this.onKeyPress = function (keyCode, character, isCtrlPressed, isShiftPressed, isAltPressed) { };
	this.onMouseDown = function (x, y, button) { };
	this.onMouseUp = function (x, y, button) { };
	this.onMouseClick = function (x, y, button) { };
	this.onMouseMove = function (x, y) { };
	this.onMouseScroll = function (delta, absolute) { };
	this.onTouchStart = function (info, index, count, event) { };
	this.onMultiTouchStart = function (touches, event) { };
	this.onTouchMove = function (info, index, count, previousInfo, event) { };
	this.onMultiTouchMove = function (touches, previousTouches, event) { };
	this.onTouchEnd = function (info, index, count, event) { };
	this.onMultiTouchEnd = function (touches, event) { };

	this.init = function (__viewportElement, layerParent) {

		thisANInput._viewportElement = __viewportElement;

		// For IE compatibility
		function addEventHandler(elem, type, fn) {
			if (elem.addEventListener)
				elem.addEventListener(type, fn, false);
			else if (elem.attachEvent) {
				elem["e" + type + fn] = fn;
				elem[type + fn] = function () { elem["e" + type + fn](window.event); }
				elem.attachEvent("on" + type, elem[type + fn]);
			}
		}

		document.onkeydown = function (event) {
			if (event == null) {
				event = window.event;
			}

			var keyCode = event.keyCode;
			var character = event.which == null ? String.fromCharCode(event.keyCode) : String.fromCharCode(event.which);
			var isCtrlPressed = event.ctrlKey ? true : false;
			var isShiftPressed = event.shiftKey ? true : false;
			var isAltPressed = event.altKey ? true : false;

			thisANInput.keyboard[keyCode] = true;
			thisANInput.keyboard['ctrl'] = isCtrlPressed;
			thisANInput.keyboard['shift'] = isShiftPressed;
			thisANInput.keyboard['alt'] = isAltPressed;

			return thisANInput.onKeyDown(keyCode, character, isCtrlPressed, isShiftPressed, isAltPressed);
		};

		document.onkeyup = function (event) {
			if (event == null) {
				event = window.event;
			}

			var keyCode = event.keyCode;
			var character = event.which == null ? String.fromCharCode(event.keyCode) : String.fromCharCode(event.which);
			var isCtrlPressed = event.ctrlKey ? true : false;
			var isShiftPressed = event.shiftKey ? true : false;
			var isAltPressed = event.altKey ? true : false;

			thisANInput.keyboard[keyCode] = false;
			thisANInput.keyboard['ctrl'] = isCtrlPressed;
			thisANInput.keyboard['shift'] = isShiftPressed;
			thisANInput.keyboard['alt'] = isAltPressed;

			return thisANInput.onKeyUp(keyCode, character, isCtrlPressed, isShiftPressed, isAltPressed);
		};

		document.onkeypress = function (event) {
			if (event == null) {
				event = window.event;
			}

			var keyCode = event.charCode;
			var character = event.which == null ? String.fromCharCode(event.keyCode) : String.fromCharCode(event.which);
			var isCtrlPressed = event.ctrlKey ? true : false;
			var isShiftPressed = event.shiftKey ? true : false;
			var isAltPressed = event.altKey ? true : false;

			return thisANInput.onKeyPress(keyCode, character, isCtrlPressed, isShiftPressed, isAltPressed);
		};

		thisANInput._viewportElement.onmousewheel = onMouseWheelChange;

		addEventHandler(thisANInput._viewportElement, 'DOMMouseScroll', onMouseWheelChange);
		addEventHandler(thisANInput._viewportElement, 'touchstart', function (event) {
			var touchCount = event.changedTouches.length;
			var touches = [];
			var touch = null;

			for (var i = 0; i < touchCount; i++) {
				touch = event.changedTouches[i];

				var touchInfo = {
					pageX: touch.pageX,
					pageY: touch.pageY,
					clientX: touch.clientX,
					clientY: touch.clientY,
					screenX: touch.screenX,
					screenY: touch.screenY,
					target: touch.target,
					identifier: touch.identifier
				};

				thisANInput.onTouchStart(touchInfo, i, touchCount, event);
				touches.push(touchInfo);
				thisANInput.previousTouchInfo[touch.identifier] = touchInfo;
			}

			if (touchCount == 1) {
				touch = event.changedTouches[0];

				var x = touch.clientX;
				var y = touch.clientY;

				if (thisANInput.touchEmulatesMouse) {
					thisANInput.mouse.x = x;
					thisANInput.mouse.y = y;
					thisANInput.mouse.left = true;

					if (thisANInput.layerParent != null) {
						thisANInput.layerParent.onMouseDown(x, y, 0);
					}

					thisANInput.onMouseDown(x, y, 0);
				}
			}
			else {
				thisANInput.onMultiTouchStart(touches, event);
			}

		}); // end of addEventListener('touchstart')


		addEventHandler(thisANInput._viewportElement, 'touchmove', function (event) {
			var touchCount = event.changedTouches.length;
			var touches = [];
			var touch = null;

			for (var i = 0; i < touchCount; i++) {
				touch = event.changedTouches[i];

				var touchInfo = {
					pageX: touch.pageX,
					pageY: touch.pageY,
					clientX: touch.clientX,
					clientY: touch.clientY,
					screenX: touch.screenX,
					screenY: touch.screenY,
					target: touch.target,
					identifier: touch.identifier
				};

				thisANInput.onTouchMove(touchInfo, i, touchCount, (typeof (thisANInput.previousTouchInfo[touch.identifier]) != 'undefined' ? thisANInput.previousTouchInfo[touch.identifier] : null), event);

				touches.push(touchInfo);
			}

			if (touchCount == 1) {
				touch = event.changedTouches[0];

				var x = touch.clientX;
				var y = touch.clientY;

				if (thisANInput.touchEmulatesMouse) {
					thisANInput.mouse.x = x;
					thisANInput.mouse.y = y;
					thisANInput.mouse.left = true;

					if (thisANInput.layerParent != null) {
						thisANInput.layerParent.onMouseMove(x, y);
					}

					thisANInput.onMouseMove(x, y);
				}
			}
			else {
				thisANInput.onMultiTouchMove(touches, thisANInput.previousTouchInfo, event);
			}

			for (var j = 0; j < touches.length; j++) {
				thisANInput.previousTouchInfo[touches[j].identifier] = touches[j];
			}
		}); // end of addEventListener('touchmove')


		addEventHandler(thisANInput._viewportElement, 'touchend', function (event) {
			var touchCount = event.changedTouches.length;
			var touches = [];
			var touch = null;

			for (var i = 0; i < touchCount; i++) {
				touch = event.changedTouches[i];

				var touchInfo = {
					pageX: touch.pageX,
					pageY: touch.pageY,
					clientX: touch.clientX,
					clientY: touch.clientY,
					screenX: touch.screenX,
					screenY: touch.screenY,
					target: touch.target,
					identifier: touch.identifier
				};

				thisANInput.onTouchEnd(touchInfo, i, touchCount, event);

				touches.push(touchInfo);

				thisANInput.previousTouchInfo[touch.identifier] = null;
			}

			if (touchCount == 1) {
				touch = event.changedTouches[0];

				var x = touch.clientX;
				var y = touch.clientY;

				if (thisANInput.touchEmulatesMouse) {
					thisANInput.mouse.x = x;
					thisANInput.mouse.y = y;
					thisANInput.mouse.left = false;

					if (thisANInput.layerParent != null) {
						thisANInput.layerParent.onMouseUp(x, y, 0);
					}

					thisANInput.onMouseUp(x, y, 0);
				}
			}
			else {
				thisANInput.onMultiTouchEnd(touches, event);
			}
		}); // end of addEventListener('touchend')


		addEventHandler(thisANInput._viewportElement, 'mousedown', function (event) {
			var x = null;
			var y = null;

			var button = typeof (event.which) != 'undefined' ? event.which : event.button;
			if (thisANInput._viewportElement.addEventListener == undefined) {
				if (button == 2) button = 3;
				else if (button == 4) button = 2;
			}

			if (button == 1) {
				thisANInput.mouse['left'] = true;
			}
			else if (button == 3) {
				thisANInput.mouse['right'] = true;
			}
			else if (button == 2) {
				thisANInput.mouse['middle'] = true;
			}


			x = event.x;
			y = event.y;
			thisANInput.mouse.x = x;
			thisANInput.mouse.y = y;

			thisANInput.onMouseDown(x, y, button);

			return true;
		}); //end of addEventListener('mousedown')


		addEventHandler(thisANInput._viewportElement, 'mouseup', function (event) {

			var x = null;
			var y = null;

			var button = typeof (event.which) != 'undefined' ? event.which : event.button;
			if (thisANInput._viewportElement.addEventListener == undefined) {
				if (button == 2) button = 3;
				else if (button == 4) button = 2;
			}

			if (button == 1) {
				thisANInput.mouse['left'] = false;
			}
			else if (button == 3) {
				thisANInput.mouse['right'] = false;
			}
			else if (button == 2) {
				thisANInput.mouse['middle'] = false;
			}

			x = event.x;
			y = event.y;

			thisANInput.mouse.x = x;
			thisANInput.mouse.y = y;

			thisANInput.onMouseUp(x, y, button);

			return true;
		}); // end of addEventListener('mouseup')


		addEventHandler(thisANInput._viewportElement, 'click', function (event) {

			var x = null;
			var y = null;

			var button = typeof (event.which) != 'undefined' ? event.which : event.button;
			if (thisANInput._viewportElement.addEventListener == undefined) {
				if (button == 2) button = 3;
				else if (button == 4) button = 2;
			}
			if (!button) button = 1;

			x = event.x;
			y = event.y;

			thisANInput.mouse.x = x;
			thisANInput.mouse.y = y;
			thisANInput.onMouseClick(x, y, button);

			return true;
		}); // end of addEventListener('mouseclick')

		addEventHandler(thisANInput._viewportElement, 'mousemove', function (event) {
			var x = null;
			var y = null;

			if (typeof (event.layerX) != 'undefined') {
				x = event.layerX;
				y = event.layerY;
			}
			else if (typeof (event.offsetX) != 'undefined') {
				x = event.offsetX;
				y = event.offsetY;
			}

			thisANInput.mouse.x = x;
			thisANInput.mouse.y = y;

			for (var layerName in thisANInput.layers) {
				thisANInput.layers[layerName].mouse = thisANInput.mouse;
				thisANInput.layers[layerName].onMouseMove(x, y);
			}

			if (thisANInput.layerParent != null) {
				thisANInput.layerParent.mouse = thisANInput.mouse;
				thisANInput.layerParent.onMouseMove(x, y);

				for (layerName in thisANInput.layerParent.layers) {
					var layer = thisANInput.layerParent.layers[layerName];

					if (layer != this) {
						layer.mouse = thisANInput.mouse;
						layer.onMouseMove(x, y);
					}
				}
			}

			thisANInput.onMouseMove(x, y);

			return true;
		}); // end of addEventListener('mousemove')



		thisANInput._viewportElement.oncontextmenu = function (event) {
			if (!event) { // For IE
				event = window.event;
			}

			//if (thisANInput.onContextMenu(event) === false) {
			//	return false;
			//}
			thisANInput.onMouseClick(event.x, event.y, 3);
			return false;
		};

	} // end of init


	var onMouseWheelChange = function (event) {
		var delta = 0;

		if (!event) { // For IE
			event = window.event;
		}

		if (event.wheelDelta) { // IE/Opera
			delta = event.wheelDelta / 120;
			// In Opera 9, delta differs in sign as compared to IE
			if (window.opera) {
				delta = -delta;
			}
		}
		else if (event.detail) { // Mozilla
			// In Mozilla, sign of delta is different than in IE. Also, delta is multiple of 3.
			delta = -event.detail / 3;
		}

		// positive delta is scrolled up, negative down
		if (delta != 0) {
			thisANInput.mouse.scroll += delta;
			thisANInput.onMouseScroll(delta, thisANInput.mouse.scroll);
		}

		// Prevent default actions caused by mouse wheel.
		if (event.preventDefault) {
			event.preventDefault();
		}

		event.returnValue = false;
	};

	if (arguments.length > 0) this.init.apply(this, arguments);

} // end of ANInput class

ANInput.prototype =
{
	keyboard: [],
	mouse: {
		left : false,
		right : false,
		middle : false,
		x : 0,
		y : 0,
		scroll : 0
	}
};

//